home *** CD-ROM | disk | FTP | other *** search
- sequential_read equ 0
- debugging equ 0
-
- .xlist
-
- HT equ 09h
- LF equ 0ah
- CR equ 0dh
- LINENEW equ CR+LF*256 ;the way a newline is stored in memory.
-
- bufseg segment public
-
- public toptop,topbot,bottop,botbot,margin
- margin equ 0
- toptop dw ?
- topbot dw ?
- bottop dw ?
- botbot dw ?
-
- extrn memsize: word
-
- public linecount, linesbefore
- linecount dw ?
- linesbefore dw ?
-
- public buffer_modified
- buffer_modified db ?
-
- extrn bufseg_size: byte
-
- bufseg ends
-
- data segment byte public
-
- ;the following externs are in 'buffers'
- extrn textseg: word
-
- insert_ds dw ?
-
- if sequential_read
- read_pointer dw ?
- endif
-
- data ends
-
- b_struc struc
- b db ?
- b_struc ends
-
- w_struc struc
- w dw ?
- w_struc ends
-
- byte_ptr label byte
-
- code segment byte public
- ;all the routines in this segment are entered with ds=data, es=data
- assume cs:code, ds:data, es:data
-
- ;the following externs are in 'buffers'
- extrn init_all_buffers: near
-
- ;the following externs are in 'marks'
- extrn init_marks: near
- extrn get_mark: near
- extrn adjust_marks_del: near
- extrn adjust_marks_ins: near
-
- ;the following externs are in 'redisp'
- extrn prevline: near
- extrn nextline: near
- extrn compute_one: near
-
- public init_memory
- init_memory:
- ;enter with ax=>first paragraph of available memory, bx=> first paragraph of
- ; unavailable memory.
- ;exit with cy if no memory available.
- call init_all_buffers
- jc init_memory_1 ;if error, don't bother continuing.
- clc
- init_memory_1:
- ret
-
-
- public count_lines
- count_lines:
- push ds
- mov ds,textseg
- call count_lines$
- pop ds
- ret
-
- public del_to_mark
- del_to_mark:
- push ds
- mov ds,textseg
- call del_to_mark$
- pop ds
- ret
-
-
- public read_mark
- read_mark:
- mov ds,textseg
- call read_mark$
- ret
-
-
- public goto_mark
- goto_mark:
- push ds
- mov ds,textseg
- call goto_mark$
- pop ds
- ret
-
-
- public insert_string
- insert_string:
- push ds
- mov ax,es ;use data for insert_ds.
- mov ds,textseg
- call insert_string$
- pop ds
- ret
-
-
- public set_column
- set_column:
- push ds
- mov ds,textseg
- call set_column$
- pop ds
- ret
-
-
- public set_line
- set_line:
- push ds
- mov ds,textseg
- call set_line$
- pop ds
- ret
-
-
- public compute_cursor
- compute_cursor:
- ;exit with dx=column.
- push ds
- mov ds,textseg
- call compute_cursor$
- pop ds
- ret
-
-
- public store_buffer_modified
- store_buffer_modified:
- push ds
- mov ds,textseg
- assume ds:bufseg
- mov buffer_modified,al
- pop ds
- assume ds:data
- ret
-
-
- public read_linecount
- read_linecount:
- mov bx,offset linecount
- jmp short read_variable
- public read_linesbefore
- read_linesbefore:
- mov bx,offset linesbefore
- jmp short read_variable
- public read_buffer_modified
- read_buffer_modified:
- mov bx,offset buffer_modified
- read_variable:
- push ds
- mov ds,textseg
- assume ds:bufseg
- mov ax,bufseg:[bx]
- pop ds
- assume ds:data
- ret
-
-
- public file_size
- file_size:
- ;exit with ax=size of the current buffer in bytes.
- mov ds,textseg
- assume ds:bufseg
- mov ax,topbot
- sub ax,toptop
- add ax,botbot
- sub ax,bottop
- push es
- pop ds
- assume ds:data
- ret
-
-
- public percent_full
- percent_full:
- ;return the percent full amount in ax.
- ;destroy ax,cx,dx.
- push ds
- mov ds,textseg
- assume ds:bufseg
- mov ax,100
- mov cx,memsize
- jcxz percent_full_1
- mov ax,botbot ;compute the size of the buffer
- sub ax,bottop
- add ax,topbot
- sub ax,toptop
- mov dx,0
- div cx
- cmp dx,0
- je percent_full_1
- inc ax
- percent_full_1:
- pop ds
- assume ds:data
- ret
-
-
- if sequential_read
- public reset_to_top
- reset_to_top:
- push es
- mov es,textseg
- assume es:bufseg
- mov ax,toptop
- mov read_pointer,ax
- pop es
- assume es:data
- ret
-
-
- public read_next
- read_next:
- mov bx,read_pointer
- push es
- mov es,textseg
- assume es:bufseg
- cmp bx,topbot ;time to switch to bottom?
- jb read_next_1 ;no.
- mov bx,bottop
- read_next_1:
- cmp bx,botbot ;end of file?
- jb read_next_2 ;no.
- stc
- jmp short read_next_3
- read_next_2:
- mov al,[bx]
- inc bx
- mov read_pointer,bx
- clc
- read_next_3:
- pop es
- assume es:data
- ret
-
-
- public goto_read
- goto_read:
- ;remember not to go to the LF part of a newline!
- ret ;for now, do nothing.
- endif
-
- if debugging
- extrn chrout: near
- extrn get_next_buffer: near
-
- public dump_bufseg
- dump_bufseg:
- mov ds,textseg
- assume ds:bufseg
-
- push linesbefore
- push linecount
- push botbot
- push bottop
- push topbot
- push toptop
-
- mov ax,es
- mov ds,ax
- assume ds:data
-
- mov ax,textseg
- call hexout
- pop ax ;toptop
- call hexout
- pop ax ;topbot
- call hexout
- pop ax ;bottop
- call hexout
- pop ax ;botbot
- call hexout
- pop ax ;linecount
- call hexout
- pop ax ;linesbefore
- call hexout
- call get_next_buffer
- ; call hexout
- ; ret
- ;fall through
- hexout:
- push ax
- mov ax,' ' ;print a leading space.
- call chrout
- pop ax
- push ax
- mov al,ah
- call byteout
- pop ax
- byteout:
- push ax
- shr al,1
- shr al,1
- shr al,1
- shr al,1
- call nibout
- pop ax
- nibout:
- and al,0fh
- add al,90h
- daa
- adc al,40h
- daa
- mov ah,0
- jmp chrout
- endif
-
- code ends
-
- code segment byte public
- ;all the code in this segment is entered with ds=bufseg, es=data
- assume cs:code, ds:bufseg, es:data
-
- ;the following externs are in 'redisp'
- extrn paint_window: near
- extrn trash_line: near
- extrn window_insert: near
- extrn window_delete: near
- extrn up_lines: near
- extrn down_lines: near
-
- public init_vars$
- init_vars$:
- mov bx,offset bufseg_size+2
- mov [bx-02].w,LINENEW
- mov toptop,bx
- mov topbot,bx
- mov bottop,bx
- mov botbot,bx
- mov [bx].w,LINENEW
- mov linecount,0
- mov linesbefore,0
- mov buffer_modified,0
- ret
-
-
- public insert_string$
- insert_string$:
- ;enter with si,cx describing the string to insert, ax=segment of string.
- ;exit with cy if there isn't enough room to insert the entire string.
- mov insert_ds,ax
- jcxz insert_string_1
- mov ax,bottop ;compute the free space.
- sub ax,topbot
- cmp ax,cx ;is there enough room for this string?
- jb insert_string_4 ;no - give error.
- mov buffer_modified,1
- insert_string_2:
- push ds
- mov ds,insert_ds
- mov ax,ds:[si] ;get an entire word, even though we might use only the low byte.
- pop ds
- cmp ax,LINENEW ;newline?
- jne insert_string_3 ;no.
- cmp cx,2 ;must be at least two chars left.
- jb insert_string_3 ;no - can't be newline.
- push cx
- push si
- call inscrlf
- pop si
- pop cx
- add si,2
- dec cx
- loop insert_string_2
- jmp short insert_string_1
- insert_string_3:
- push cx
- push si
- call insone
- pop si
- pop cx
- inc si
- loop insert_string_2
- insert_string_1:
- clc
- ret
- insert_string_4:
- stc
- ret
-
-
- insone:
- cmp al,CR
- jne insone_1
- mov bx,bottop
- cmp [bx].b,LF
- jne inschar
- inc bottop
- jmp short insone_2
- insone_1:
- cmp al,LF
- jne inschar
- mov bx,topbot
- cmp [bx-01].b,CR
- jne inschar
- dec topbot
- insone_2:
- mov ax,1
- call adjust_marks_del
- call inscrlf
- ret
-
- inschar:
- ;insert the character in al at the point.
- ;unless there is no room.
- mov bx,topbot
- cmp bx,bottop
- jae inschar_1
- push ax
- mov ax,1
- call adjust_marks_ins
- pop ax
- mov di,topbot
- mov [di],al
- inc di
- mov topbot,di
- call trash_line
- inschar_1:
- ret
-
-
- inscrlf:
- mov bx,topbot
- inc bx
- cmp bx,bottop
- jae inscrlf_3
-
- mov ax,2
- call adjust_marks_ins
-
- mov di,topbot
- mov [di].w,LINENEW
- add di,2
- mov topbot,di
-
- inc linesbefore
- inc linecount
-
- call window_insert ;say that we inserted a line here.
-
- inscrlf_3:
- ret
-
-
- del_to_mark$:
- call get_mark
- jcxz del_to_mark_4_j_1
- mov buffer_modified,1
- jc del_to_mark_2 ;go if point>mark
- push bottop
- call move_point_backward ;swap point and mark (sort of).
- pop si ;pushed as bottop.
- del_to_mark_2:
- mov di,toptop ;are we at the beginning of the file?
- cmp di,topbot
- jne del_to_mark_1 ;no
- cmp si,botbot ;deleting to the end of the file?
- jne del_to_mark_1 ;no
- mov ax,si
- sub ax,bottop ;compute the number of chars deleted.
- mov bottop,si ;no characters left.
- call adjust_marks_del
- mov linecount,0 ;no lines left.
- call paint_window ;trash the window.
- del_to_mark_4_j_1:
- jmp short del_to_mark_4 ;now exit.
- del_to_mark_1:
- mov bp,si ;save the char that we delete to.
- mov ax,si ;compute the number of chars.
- sub ax,bottop
- call adjust_marks_del ;fix up the marks first.
- mov si,bottop ;get the -> first char to delete.
- del_to_mark_3:
- cmp [si].w,LINENEW ;a newline?
- jne del1_1 ;no - just skip this char.
- inc si ;extra inc to skip past the CR.
- dec linecount ;one less line.
- call window_delete ;fix up the window.
- del1_1:
- inc si
- cmp bp,si
- jne del_to_mark_3
- mov bottop,si
- call trash_line
- ;now check for a newly created newline.
- mov bx,topbot
- cmp [bx-1].b,CR
- jne del_to_mark_4
- mov bx,bottop
- cmp [bx].b,LF
- jne del_to_mark_4
- ;get rid of the LF and CR seperately so that any mark that points to either
- ; one will point to the newline.
- inc bottop ;get rid of the LF
- mov ax,1
- call adjust_marks_del
- dec topbot ;get rid of the CR
- mov ax,1
- call adjust_marks_del
- call inscrlf ;now insert a newline.
- del_to_mark_4:
- ret
-
-
- public goto_mark$
- goto_mark$:
- call get_mark
- jcxz goto_mark_1
- jnc goto_mark_2
- call move_point_forward
- jmp short goto_mark_1
- goto_mark_2:
- call move_point_backward
- goto_mark_1:
- ret
-
-
- public read_mark$
- read_mark$:
- call get_mark
- jnc read_mark_1
- mov si,bottop
- read_mark_1:
- ret
-
-
- move_point_backward:
- mov si,topbot
- mov di,bottop
- push es
- push ds
- pop es
- std
- dec si
- dec di
- push cx
- rep movsb
- pop cx
- inc si
- inc di
- cld
- pop es
- mov topbot,si
- mov bottop,di
- call count_lines$
- sub linesbefore,bx
- call up_lines
- ret
-
-
- move_point_forward:
- mov si,bottop
- mov di,topbot
- push di
- push cx
- push es
- push ds
- pop es
- rep movsb
- pop es
- mov bottop,si
- mov topbot,di
- pop cx
- pop di
- call count_lines$
- add linesbefore,bx
- call down_lines
- ret
-
-
- count_lines$:
- ;count the number of newlines contained in the text described by ds:di,cx.
- push es
- push ds
- pop es
- mov bx,0
- count_lines_1:
- mov al,CR
- repnz scasb
- jcxz count_lines_2
- cmp [di].b,LF
- jne count_lines_1
- inc bx
- jmp count_lines_1
- count_lines_2:
- pop es
- ret
-
-
- public set_line$
- set_line$:
- ;given a line number in ax, move to that line.
- dec ax ;linesbefore is zero based.
- or ax,ax ;if negative, use zero.
- jns set_line_0
- xor ax,ax
- set_line_0:
- sub ax,linesbefore
- je set_line_1 ;go if we're already on that line.
- jb set_line_2 ;go if we're after that line.
- mov cx,ax
- mov si,bottop
- set_line_4:
- call nextline
- loopne set_line_4
- mov cx,si ;compute the number of characters.
- sub cx,bottop
- call move_point_forward
- jmp short set_line_1
- set_line_2:
- neg ax ;ax is the number of lines to move.
- mov cx,ax
- mov si,topbot
- cmp [si-2].w,LINENEW ;are we at the beginning of a line?
- je set_line_3 ;yes.
- call prevline ;no, go to the beginning of the line.
- set_line_3:
- call prevline
- loopne set_line_3
- mov cx,topbot ;compute the number of characters.
- sub cx,si
- call move_point_backward
- set_line_1:
- ret
-
-
- set_column$:
- ;given a column number in ax, move to that column.
- mov bx,ax ;save the column number in bx.
- dec bx ;columns are zero based.
- mov si,topbot
- jmp short set_column$_2
- set_column$_1:
- dec si
- set_column$_2:
- cmp [si-2].w,LINENEW
- jne set_column$_1
- ;now move over to the point, counting the size of characters on the way.
- mov dx,0
- mov cx,topbot
- sub cx,si
- jcxz set_column$_3
- set_column$_4:
- cmp dx,bx ;are we at or past the desired column?
- jae set_column$_6 ;yes - move the point backward.
- lodsb
- call compute_one
- loop set_column$_4
- set_column$_3:
- ;the desired column is somewhere after the point.
- mov si,bottop
- set_column$_7:
- cmp dx,bx ;are we at or past the desired column?
- jae set_column$_5 ;yes - go to the column.
- cmp [si].w,LINENEW ;are we at the end of the line?
- je set_column$_5 ;yes - this is as close as we can get.
- lodsb ;compute the next character.
- call compute_one
- jmp set_column$_7
- set_column$_5:
- mov cx,si
- sub cx,bottop
- call move_point_forward
- ret
- set_column$_6:
- call move_point_backward
- ret
-
-
- public compute_cursor$
- compute_cursor$:
- ;return the column in dx.
- ;find the beginning of this line.
- mov si,topbot
- jmp short compute_cursor$_2
- compute_cursor$_1:
- dec si
- compute_cursor$_2:
- cmp [si-2].w,LINENEW
- jne compute_cursor$_1
- ;now move over to the point, counting the size of characters on the way.
- mov dx,0
- mov cx,topbot
- sub cx,si
- jcxz compute_cursor$_3
- compute_cursor$_4:
- lodsb
- call compute_one
- loop compute_cursor$_4
- compute_cursor$_3:
- ret
-
-
- code ends
-
- end